home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / asmutil / asm_n_z.zip / SWEEP.ASM < prev    next >
Assembly Source File  |  1986-06-04  |  10KB  |  325 lines

  1. ;    SWEEP.ASM -- Runs program or command across subdirectories
  2. ;    =========
  3. ;
  4. ;        (C) Copyright Charles Petzold, 1985
  5.  
  6. CSEG        Segment
  7.         Assume    CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
  8.  
  9.         Org    002Ch
  10. Environment    Label    Byte        ; Segment of Environment is here
  11.  
  12.         Org    007Dh
  13. NewParam    Label    Byte        ; Parameter to pass to COMMAND
  14.  
  15.         Org    0080h
  16. OldParam    Label    Byte        ; Parameter passed to SWEEP
  17.  
  18.         Org    0100h
  19. Entry:        Jmp    Begin        ; SWEEP.COM Entry Point
  20.  
  21. ;    Most Data (some more at end of program)
  22. ;    ---------
  23.  
  24. SweepMessage    db    13,10,'>>> SWEEP >>> '    ; The SWEEP message
  25. CurrentDir    db    ?,':\'            ; ? gets drive letter
  26.  
  27.         db    '(C) Copyright Charles Petzold, 1985',1Ah
  28.  
  29. DosVersMsg    db    'Needs DOS 2.0 +$'    ; Error Messages
  30. MemAllocMsg    db    'Allocation Problem$'
  31. CommandMsg    db    'SWEEP: COMMAND Problem$'
  32. AbnormalMsg    db    'SWEEP: Abnormal Exit$'
  33.  
  34. DosVersion    dw    ?        ; Store DOS Version Number here
  35. BreakState    db    ?        ; Store original break state here
  36.  
  37. Comspec        db    'COMSPEC='    ; String for Environment search
  38. CommandAsciiz    dd    ?        ; Address of COMMAND.COM string
  39. ParamBlock    dw    ?        ; Parameter block for EXEC call
  40.         dw    NewParam,?
  41.         dw    5Ch,?
  42.         dw    6Ch,?
  43.  
  44. SearchAsciiZ    db    '*.*',0        ; Asciiz for Find call
  45. BackOneDir    db    '..',0        ; Asciiz for moving back one directory
  46. DtaPointer    dw    DtaAreaBegin    ; For nested directory searches
  47. Direction    db    0        ; Forward search initially
  48.  
  49. ;    Check DOS Version
  50. ;    -----------------
  51.  
  52. Begin:        Mov    AH,30h            ; Check for DOS Version
  53.         Int    21h
  54.         Cmp    AL,2            ; See if it's 2.0 or above
  55.         Jae    DosVersOK        ; If so, we can proceed
  56.  
  57.         Mov    DX,Offset DosVersMsg    ; Otherwise error message
  58. ErrorExit:    Mov    AH,9            ; Print String function call
  59.         Int    21h            ; Do it
  60.  
  61.         Int    20h            ; And exit prematurely
  62.  
  63. DosVersOK:    Xchg    AL,AH            ; Get Major Version in AH
  64.         Mov    [DosVersion],AX        ; And save whole thing
  65.  
  66. ;    Un-allocate rest of memory 
  67. ;    --------------------------
  68.  
  69.         Mov    SP,Offset StackTop    ; Set new stack pointer
  70.         Mov    BX,Offset EndOfProgram    ; This is beyond our needs
  71.         Mov    CL,4            ; Prepare for shift
  72.         Shr    BX,CL            ; Convert to segment form
  73.         Mov    AH,4Ah            ; Shrink allocated memory
  74.         Int    21h            ; By calling DOS
  75.  
  76.         Jnc    MemAllocOK        ; If no error, we can proceed
  77.  
  78.         Mov    DX,Offset MemAllocMsg    ; Otherwise set up for message
  79.         Jmp    ErrorExit        ; Print it and terminate
  80.  
  81. ;    Search for Comspec in Environment
  82. ;    ---------------------------------
  83.  
  84. MemAllocOK:    Push    ES            ; We'll be changing this
  85.         Mov    BX,Offset Environment    ; Segment of Environment
  86.         Mov    ES,[BX]            ; Set ES to it
  87.         Assume    ES:Nothing        ; And tell the assembler
  88.  
  89.         Sub    DI,DI            ; Start at the beginning
  90.         Mov    SI,Offset ComSpec    ; String to search for
  91.         Cld                ; Direction must be forward
  92.  
  93. TryThis:    Cmp    Byte Ptr ES:[DI],0    ; See if points to zero
  94.         Jz    NoFindComSpec        ; If so, we're dead in water
  95.         
  96.         Push    SI            ; Temporarily save these
  97.         Push    DI
  98.         
  99.         Mov    CX,8            ; Search string has 8 chars
  100.         Repz    Cmpsb            ; Do the string compare
  101.  
  102.         Pop    DI            ; Get back the registers
  103.         Pop    SI
  104.  
  105.         Jz    FoundComspec        ; If equals, we've found it
  106.  
  107.         Sub    AL,AL            ; Otherwise search for zero
  108.         Mov    CX,-1            ; For 'infinite' bytes 
  109.         Repnz    Scasb            ; Do the search
  110.  
  111.         Jmp    TryThis            ; And try the next string
  112.  
  113. NoFindComSpec:    Pop    ES            ; Get back ES on error
  114.         Mov    DX,Offset CommandMsg    ; Set up error message
  115.         Jmp    ErrorExit        ; And bow out gracefully
  116.  
  117. FoundComspec:    Add    DI,8            ; so points after 'COMSPEC='
  118.         Mov    Word Ptr [CommandASCIIZ],DI    ; Save the address
  119.         Mov    Word Ptr [CommandASCIIZ + 2],ES    ; including segment
  120.  
  121. ;     Set up parameter block for EXEC call
  122. ;    ------------------------------------
  123.  
  124.         Mov    [ParamBlock],ES        ; Segment of environment
  125.         Mov    [ParamBlock + 4],CS    ; Segment of parameter
  126.         Mov    [ParamBlock + 8],CS    ; Segment of 1st FCB
  127.         Mov    [ParamBlock + 12],CS    ; Segment of 2nd FCB
  128.  
  129.         Pop    ES            ; Restores ES to this segment
  130.         Assume    ES:CSEG            ; And make sure MASM knows
  131.  
  132. ;    Fix up new paramater for "/C" String
  133. ;    ------------------------------------
  134.  
  135.         Mov    AL,[OldParam]    ; Get old character count
  136.         Add    AL,3        ; Three more characters in paramater
  137.         Mov    [NewParam],AL    ; New number of characters
  138.         Mov    [NewParam + 1],' '        ; Next is a blank
  139.         Mov    Word Ptr [NewParam + 2],'C/'    ; Then a /C
  140.  
  141. ;    Get the current break state, drive, and subdirectory
  142. ;    ----------------------------------------------------
  143.  
  144.         Mov    AX,3300h        ; Get Break State
  145.         Int    21h            ; By calling DOS
  146.         Mov    [BreakState],DL        ; Save it
  147.  
  148.         Sub    DL,DL            ; Set it to OFF
  149.         Mov    AX,3301h        ; Set Break State
  150.         Int    21h            ; By calling DOS
  151.  
  152.         Mov    DX,Offset Terminate    ; For Ctrl-Break exits
  153.         Mov    AX,2523h        ; Set Interrupt 23h vector
  154.         Int    21h            ;    through DOS call
  155.  
  156.         Mov    AH,19h            ; Get current drive
  157.         Int    21h            ; By calling DOS
  158.         Add    AL,'A'            ; Convert to letter
  159.         Mov    [CurrentDir],AL        ; And save it
  160.  
  161.         Mov    SI,Offset StartOffDir    ; Repository of directory
  162.         Sub    DL,DL            ; Indicate default drive
  163.         Mov    AH,47h            ; Get current directory
  164.         Int    21h            ; By calling DOS
  165.  
  166. ;    Display SWEEP message with current drive and subdirectory
  167. ;    ---------------------------------------------------------
  168.  
  169. MainLoop:    Mov    SI,3 + Offset CurrentDir; Receives directory
  170.         Sub    DL,DL            ; Indicate current drive
  171.         Mov    AH,47h            ; Current directory call
  172.         Int    21h            ; Get it
  173.  
  174.         Mov    SI,Offset SweepMessage    ; String to display
  175.         Cld                ; Want direction forward
  176. DirPrintLoop:    Lodsb                ; Get the character
  177.         Or    AL,AL            ; Check if it's zero
  178.         Jz    NoMoreDirPrint        ; If so, branch out
  179.         Mov    DL,AL            ; Otherwise set DL to it
  180.         Mov    AH,2            ; For Display Output
  181.         Int    21h            ; Display the character
  182.         Jmp    DirPrintLoop        ; And loop around for the next
  183.  
  184. NoMoreDirPrint:    Mov    CX,500            ; We'll hang out here awhile
  185.  
  186. StatCheckLoop:    Mov    AH,0Bh            ; Set up for keyboard status
  187.         Int    21h            ; Allow user to Break out
  188.         Loop    StatCheckLoop        ; Do it a few more times
  189.  
  190.         Cmp    [DosVersion],30Ah    ; See if DOS is 3.1 or higher
  191.         Jb    LoadCommand        ; If not, skip CR & LF
  192.  
  193.         Mov    DL,13            ; Carriage Return
  194.         Mov    AH,2            ; Write to Display
  195.         Int    21h            ;   by calling DOS
  196.  
  197.         Mov    DL,10            ; Line Feed
  198.         Mov    AH,2            ; Write to Display
  199.         Int    21h            ;   by calling DOS
  200.  
  201. ;     Load COMMAND.COM
  202. ;     -----------------
  203.         
  204. LoadCommand:    Mov    BX,Offset ParamBlock    ; ES:BX = parameter block
  205.         Lds    DX,[CommandAsciiz]    ; DS:DX = Asciiz of COMMAND
  206.         Sub    AL,AL            ; EXEC type zero
  207.         Mov    AH,4Bh            ; EXEC function call
  208.         Int    21h            ; Load command processor
  209.  
  210. ;     Return from COMMAND.COM
  211. ;    -----------------------
  212.  
  213.         Mov    AX,CS        ; This is the current code segment
  214.         Mov    DS,AX        ; Reset DS to this segment
  215.         Mov    ES,AX        ; Reset ES to this segment
  216.         Mov    SS,AX        ; Reset stack segment to it
  217.         Mov    SP,Offset StackTop    ; And reset stack pointer also
  218.  
  219. ;    Avoid problems caused by commands that may change drive or directory
  220. ;    --------------------------------------------------------------------
  221.  
  222.         PushF                ; Save EXEC Error Flag
  223.  
  224.         Sub    DL,DL            ; Set Break State to OFF
  225.         Mov    AX,3301h        ; Set Break State
  226.         Int    21h            ; By calling DOS
  227.  
  228.         Mov    DL,[CurrentDir]        ; Get original drive letter
  229.         Sub    DL,'A'            ; Convert to number
  230.         Mov    AH,0Eh            ; Select disk
  231.         Int    21h            ; Through DOS call
  232.  
  233.         PopF                ; Get back EXEC Error Flag
  234.  
  235.         Mov    DX,Offset CommandMsg    ; Set up possible error message
  236.         Jc    ErrorExit2        ; And print if EXEC error
  237.  
  238.         Mov    DX,2 + Offset CurrentDir; The pre-COMMAND directory
  239.         Mov    AH,3Bh            ; Call to change directory
  240.         Int    21h            ; Do it
  241.  
  242.         Jnc    NextLevel        ; Continue if no error
  243.  
  244.         Mov    DX,Offset AbnormalMsg    ; Otherwise set up message
  245. ErrorExit2:    Mov    AH,9            ; Will print the string
  246.         Int    21h            ; Print it
  247.  
  248.         Jmp    Terminate        ; And get out of here
  249.  
  250. ;    Find first or next subdirectory level
  251. ;    -------------------------------------
  252.  
  253. NextLevel:    Mov    DX,[DTAPointer]        ; Next nested DTA
  254.         Mov    AH,1Ah            ; For DOS call to set DTA
  255.         Int    21h            ; Do it
  256.  
  257.         Cmp    [Direction],0        ; Check if we're nesting
  258.         Jnz    FindNextFile        ; If not, we're continuing
  259.  
  260.         Mov    DX,Offset SearchAsciiZ    ; We search for *.*
  261.         Mov    CX,10h            ; Subdirectory attribute
  262.         Mov    AH,4Eh            ; Find first file
  263.         Int    21h            ;   by calling DOS
  264.  
  265.         Jmp    Short TestMatch        ; Hop around next section
  266.  
  267. FindNextFile:    Mov    AH,4Fh            ; Find next file 
  268.         Int    21h            ;   by calling DOS
  269.  
  270. TestMat